package com.buaa.aimall.modelModule.Controller;

import com.alibaba.fastjson.JSONObject;
import com.buaa.aimall.Utils.Client.KongAPIGatewayClient;
import com.buaa.aimall.modelModule.Converter.ModelConvert;
import com.buaa.aimall.modelModule.DTO.*;
import com.buaa.aimall.modelModule.Entity.ModelAPIEntity;
import com.buaa.aimall.modelModule.Entity.ModelEntity;
import com.buaa.aimall.modelModule.Enum.ModelRatingEnum;
import com.buaa.aimall.modelModule.Enum.ModelStatusEnum;
import com.buaa.aimall.Utils.Enum.StatusCode;
import com.buaa.aimall.Utils.Exception.BusinessException;
import com.buaa.aimall.modelModule.Service.ModelAPIService;
import com.buaa.aimall.modelModule.Service.ModelService;
import com.buaa.aimall.Utils.BaseResponse;
import com.buaa.aimall.Utils.PageReturnResult;

import com.buaa.aimall.userModule.DTO.IdDTO;
import com.buaa.aimall.userModule.Entity.UserEntity;
import com.buaa.aimall.userModule.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.validation.Valid;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/model/model")
@CrossOrigin
public class ModelController {

    @Autowired
    private ModelService modelService;

    @Autowired
    private UserService userService;

    @Autowired
    private ModelAPIService modelAPIService;

    @Autowired
    private KongAPIGatewayClient kongAPIGatewayClient;

    @PostMapping("/test-kong")
    public BaseResponse<Boolean> testKong(@RequestBody Map<String, String> request) {
        var name = request.get("name");
        var response = kongAPIGatewayClient.createRoutesForService(name);
        var body = JSONObject.parseObject(response.getBody());
        System.out.println(body.getJSONArray("paths").get(0));
        return new BaseResponse<>(StatusCode.SUCCESS, "ok", true);
    }

    @PostMapping("/create-model")
    public BaseResponse<Boolean> createModel(@Valid ModelDTO request) {
        ModelEntity modelEntity = ModelConvert.INSTANCE.createModelDTOToEntity(request);
        modelEntity.setCreator(userService.getCurrentUser().getId());

        // API网关创建一个新的service
        String kongServiceName = request.getNameEN() + "_" + UUID.randomUUID().toString().substring(24);
        try {
            var response = kongAPIGatewayClient.createServices(kongServiceName, request.getAPIURL());
            if (response.getStatusCode() != HttpStatus.CREATED) {
                return new BaseResponse<>(StatusCode.KONG_API_GATEWAY_ERROR, "Kong API网关 服务创建失败", false);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new BaseResponse<>(StatusCode.KONG_API_GATEWAY_ERROR, "Kong API网关请求出错", false);
        }
        var modelApiEntity = ModelAPIEntity.builder()
                .url(request.getAPIURL())
                .kongServiceName(kongServiceName)
                .build();
        modelAPIService.save(modelApiEntity);
        modelEntity.setFkModelApi(modelApiEntity.getId());

        Boolean result;
        try {
            result = modelService.createModel(modelEntity, request.getDocFile());
        } catch (BusinessException ex) {
            return new BaseResponse<>(StatusCode.DAO_ERROR, ex.getMessage(), null);
        }
        return new BaseResponse<>("创建模型", result, result);
    }

    @GetMapping("/get-model-by-id")
    public BaseResponse<ModelEntity> getModelById(@Valid IdDTO request) {
        ModelEntity modelEntity = modelService.getById(request.getId());
        return new BaseResponse<>("根据id查询模型成功", "模型不存在", modelEntity != null, modelEntity);
    }

    @PostMapping("/delete-model-by-id")
    public BaseResponse<Boolean> deleteModelById(@Valid @RequestBody IdDTO request) {
        Boolean result = modelService.removeById(request.getId());
        return new BaseResponse<>("根据id删除模型成功", "模型不存在或已删除", result, result);
    }

    @PostMapping("/update-model")
    public BaseResponse<Boolean> updateModel(@Valid @RequestBody ModelDTO request) {
        ModelEntity modelEntity = ModelConvert.INSTANCE.createModelDTOToEntity(request);
        Boolean result = modelService.updateById(modelEntity);
        return new BaseResponse<>("修改模型", result, result);
    }

    @GetMapping("get-model-list-from-compute")
    public BaseResponse<ModelEntity> getModelListFromCompute() {
        ModelEntity modelEntity1 = new ModelEntity();
        modelEntity1.setId("7fceb1b7-4774-4b8b-aa69-ecbb7de2b3b8");
        modelEntity1.setNameEN("Tiny-YOLOv4");
        modelEntity1.setNameZH("微型-YOLOv4");
        modelEntity1.setType("CV");
        modelEntity1.setCreator("Darknet Team");
        modelEntity1.setDescription("这是一个轻量级版本的YOLOv4模型，专为实时目标检测优化，适用于边缘设备。");
        modelEntity1.setCreateTime(LocalDateTime.now().minusYears(1)); // 当前时间往前推1年
        modelEntity1.setVersion("4.2.1");
        modelEntity1.setDocURL("https://example.com/docs/tiny-yolov4");
        modelEntity1.setImageURL("https://example.com/images/tiny-yolov4.png");
        modelEntity1.setImageURLBackup("https://backup.example.com/images/tiny-yolov4.png");
        modelEntity1.setIsEnabled(true);
        modelEntity1.setRating(ModelRatingEnum.B);
        modelEntity1.setMemorySize(35.0);
        modelEntity1.setPriceByDay(99);
        modelEntity1.setPriceByWeek(650);
        modelEntity1.setPriceByMonth(2500);
        modelEntity1.setPriceByTimes(20); // 每次使用的费用
        modelEntity1.setStatus(ModelStatusEnum.B); // 假设有一个状态枚举ACTIVE表示激活状态
        modelEntity1.setUpdateTime(LocalDateTime.now());

        return new BaseResponse<>(StatusCode.SUCCESS, "查询成功", modelEntity1);
    }

    @GetMapping("get-model-average-price")
    public BaseResponse<JSONObject> getAveragePriceOfModelOfSameType(@Valid GetModelPriceDTO request) {
        JSONObject result = new JSONObject();
        result.put("priceByTimes", 3.4);
        result.put("priceByDay", 20.6);
        result.put("priceByWeek", 120.7);
        result.put("priceByMonth", 300.2);
        return new BaseResponse<>(StatusCode.SUCCESS, "获取平均价格成功", result);
    }

    @GetMapping("/get-model-list")
    public BaseResponse<List<ModelEntity>> getModelList(@Valid GetModelListDTO request) {
        List<ModelEntity> modelList = modelService.getModelList(request);
        return new BaseResponse<>(StatusCode.SUCCESS, "查询成功", modelList);
    }

    @PostMapping("/filter-model")
    public BaseResponse<PageReturnResult<ModelEntity>> filterModel(@Valid @RequestBody FilterModelDTO filterModelDTO) {
        UserEntity userEntity = userService.getCurrentUser();
        filterModelDTO.setFk_creator(userEntity.getId());
        PageReturnResult<ModelEntity> modelList = modelService.filterModel(filterModelDTO);
        return new BaseResponse<>(StatusCode.SUCCESS, "查询成功", modelList);
    }

    @PostMapping("/remove-model")
    public BaseResponse<Boolean> removeModel(@Valid @RequestBody IdDTO request) {
        boolean result;
        try {
            result = modelService.disableModel(request.getId());
        } catch (BusinessException ex) {
            return new BaseResponse<>(StatusCode.DAO_ERROR, ex.getMessage(), null);
        }
        return new BaseResponse<>("模型下架", result, result);
    }

    @PostMapping("/enable-model")
    public BaseResponse<Boolean> enableModel(@Valid @RequestBody IdDTO request) {
        boolean result;
        try {
            result = modelService.enableModel(request.getId());
        } catch (BusinessException ex) {
            return new BaseResponse<>(StatusCode.DAO_ERROR, ex.getMessage(), null);
        }
        return new BaseResponse<>("模型上架", result, result);
    }

    @PostMapping("/update-model-doc")
    public BaseResponse<Boolean> updateModelDoc(
            @RequestParam("id") String modelID,
            @RequestPart("docFile") MultipartFile docFile
    ) {
        try {
            Boolean result = modelService.updateModelDoc(modelID, docFile);
            return new BaseResponse<>(StatusCode.SUCCESS, "文档更新成功", result);
        } catch (BusinessException e) {
            return new BaseResponse<>(StatusCode.DAO_ERROR, e.getMessage(), false);
        }
    }

    @GetMapping("/report")
    public BaseResponse<JSONObject> getModelReport(@Valid IdDTO request) {
        JSONObject result = new JSONObject();
        result.put("roc", 1.1);
        result.put("pr", 2.2);
        result.put("responseTime", 3.3);
        result.put("memorySize", 512);
        result.put("rank", 10);
        return new BaseResponse<>(StatusCode.SUCCESS, "获取模型报告成功", result);
    }
}
